﻿ko.dirtyFlag = function (root, isInitiallyDirty) {
    var result = function () { },
        _initialState = ko.observable(ko.toJSON(root)),
        _isInitiallyDirty = ko.observable(isInitiallyDirty);

    result.isDirty = ko.computed(function () {
        if (root.IsDirty != null) {
            root.IsDirty(true);
            return root.IsDirty();
        }
        return _isInitiallyDirty() || _initialState() !== ko.toJSON(root);
    });
    return result;
};

if (ko != null) {
    ko.observableArray.fn.setAt = function (index, value, viewModel) {
        this.replace(this()[index], value);
    }

    ko.bindingHandlers.ckeditor = {
        init: function (element, valueAccessor, allBindingsAccessor, context) {
            var options = allBindingsAccessor().ckeditorOptions || {};
            var modelValue = valueAccessor();
            var value = ko.utils.unwrapObservable(valueAccessor());

            CKEDITOR.disableAutoInline = true;

            $(element).html(value);

            var config = {
                toolbar:
                [
                    ['Bold', 'Italic', 'Underline', '-', 'NumberedList', 'BulletedList', '-', 'Undo', 'Redo', '-', 'SelectAll'],
                    ['UIColor']
                ]
            };
            $(element).ckeditor(function () { }, config);
            var editor = $(element).ckeditorGet();

            editor.on('change', function (e) {
                var self = this;
                if (ko.isWriteableObservable(self)) {
                    self($(e.listenerData).val());
                }
            }, modelValue, element);
            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                if (editor) {
                    CKEDITOR.remove(editor);
                };
            });
        },
        update: function (element, valueAccessor, allBindingsAccessor, context) {
            var newValue = ko.utils.unwrapObservable(valueAccessor());
            if ($(element).ckeditorGet().getData() != newValue)
                $(element).ckeditorGet().setData(newValue)
        }
    };

}


ko.bindingHandlers.wysiwyg = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        var valueUnwrapped = ko.unwrap(value);
        var allBindings = allBindingsAccessor();
        var $element = $(element);
        $element.attr('contenteditable', true);
        if (ko.isObservable(value)) {
            var isSubscriberChange = false;
            var isEditorChange = true;
            $element.html(value());
            var isEditorChange = false;

            $element.on('blur', function (e) {
                if (!isSubscriberChange) {
                    var self = this;
                    if (ko.isWriteableObservable(value)) {
                        value($element.html());
                    }
                    return;
                    isEditorChange = true;
                    value($element.html());
                    isEditorChange = false;
                }
            });
            value.subscribe(function (newValue) {
                if (!isEditorChange) {
                    isSubscriberChange = true;
                    $element.html(newValue);
                    isSubscriberChange = false;
                }
            });
        }
    }
}

String.prototype.endsWith = function (suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};

/** endswith function http://stackoverflow.com/questions/280634/endswith-in-javascript */
if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function (suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}
/**
 * ReplaceAll by Fagner Brack (MIT Licensed)
 * Replaces all occurrences of a substring in a string
 */
String.prototype.replaceAll = function (token, newToken, ignoreCase) {
    var _token;
    var str = this + "";
    var i = -1;

    if (typeof token === "string") {

        if (ignoreCase) {

            _token = token.toLowerCase();

            while ((
                i = str.toLowerCase().indexOf(
                    token, i >= 0 ? i + newToken.length : 0
                )) !== -1
            ) {
                str = str.substring(0, i) +
                    newToken +
                    str.substring(i + token.length);
            }

        } else {
            return this.split(token).join(newToken);
        }

    }
    return str;
};

